package scu.maqiang.tiangong;

import scu.maqiang.mesh.*;
import scu.maqiang.numeric.MVO;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;

public class Read2CMesh {
    public static void main(String[] args) {
/*
        String dir = "TianGongMeshes\\";
        String dataFile = dir + "TG-2C_80000m.dat";

        Scanner scanner = null;
        try {
            scanner = new Scanner(new File(dataFile));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        int numberOfNodes = scanner.nextInt();
        int numberOfElements = scanner.nextInt();
        double[][] nodesData = new double[numberOfNodes][];
        double[] pressureData = new double[numberOfNodes];
        double[] heatFluxData = new double[numberOfNodes];
        double[] fricData = new double[numberOfNodes];
        double[] xyz0 = new double[3];
        for(int i = 0; i < numberOfNodes; i++) {
            nodesData[i] = new double[3];
            nodesData[i][0] = scanner.nextDouble();
            nodesData[i][1] = scanner.nextDouble();
            nodesData[i][2] = scanner.nextDouble();
            fricData[i]     = scanner.nextDouble();
            pressureData[i] = scanner.nextDouble();
            heatFluxData[i] = scanner.nextDouble();
        }
        int[][] elesData = new int[numberOfElements][];
        for(int i = 0; i < numberOfElements; i++) {
            elesData[i] = new int[3];
            elesData[i][0] = scanner.nextInt() - 1;
            elesData[i][1] = scanner.nextInt() - 1;
            elesData[i][2] = scanner.nextInt() - 1;
        }
        Mesh3T3SGenerator mg = new Mesh3T3SGenerator();
        Mesh3T3S mesh = mg.constructMesh(nodesData, elesData);
        ScalarFunc rightRegion = (xyz, label, param) -> xyz[0] > -4.6?1.0:-1.0;
        mesh.removeElements(rightRegion, null, 1);
        mesh.saveMesh_mesh("Half2D.mesh");
        mesh.saveMesh("MyHalf2DD.msh");
*/


        String dir = "C:\\Users\\Administrator\\OneDrive\\TianGongComputation\\TianGong2CComputations\\";
        String meshFile = dir + "Whole2CMesh2.mesh";
        Mesh3T4 mesh = new Mesh3T4().readMesh(meshFile, MeshFormat.mesh);
        String dataFile = dir + "TG-2C_110000m.dat";
        Scanner scanner = null;
        try {
            scanner = new Scanner(new File(dataFile));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        int numberOfNodes = scanner.nextInt();
        int numberOfElements = scanner.nextInt();
        double[][] nodesData = new double[numberOfNodes][];
        double[] pressureData = new double[numberOfNodes];
        double[] heatFluxData = new double[numberOfNodes];
        double[] fricData = new double[numberOfNodes];
        double[] xyz0 = new double[3];
        for(int i = 0; i < numberOfNodes; i++) {
            nodesData[i] = new double[3];
            nodesData[i][0] = scanner.nextDouble();
            nodesData[i][1] = scanner.nextDouble();
            nodesData[i][2] = scanner.nextDouble();
            fricData[i]     = scanner.nextDouble();
            pressureData[i] = scanner.nextDouble();
            heatFluxData[i] = scanner.nextDouble();
        }

        double min = 1.0e10;
        int idx = -1;
        boolean flag = false;
        int count = 0;
        int numberOfMeshNodes = mesh.getNv();
        double[] pressureDataInMesh = new double[numberOfMeshNodes];
        double[] heatFluxDataInMesh = new double[numberOfMeshNodes];
        for(int i = 0; i < numberOfMeshNodes; i++) {
            double[] xyz = mesh.getNode(i);
            min = 1.0e10;
            idx = -1;
            flag = false;
            for(int j = 0; j < numberOfNodes; j++) {
                double[] nodeData = nodesData[j];
                double error = MVO.distance(xyz, nodeData);
                if (min > error) {
                    min = - error;
                    idx = j;
                }
                if (error < 1.0e-4) {
                    pressureDataInMesh[i] = pressureData[j];
                    heatFluxDataInMesh[i] = heatFluxData[j];
                    System.out.println("count: " +(++count));
                    flag = true;
                    break;
                }
            }
        }
        scanner.close();
        mesh.toTecplot(dir + "PressureData_110000m.dat", pressureDataInMesh);
        mesh.toTecplot(dir + "HeatFluxData_110000m.dat", heatFluxDataInMesh);
        MVO.saveArray(dir + "PressureData_110000m.txt", pressureDataInMesh);
        MVO.saveArray(dir + "HeatFluxData_110000m.txt", heatFluxDataInMesh);


        /*
        //Mesh3T4Generator mg = new Mesh3T4Generator();
        String dir = "C:\\Users\\Administrator\\OneDrive\\TianGongComputation\\T100Computations\\";
        //String meshFile = dir + "Whole2CMesh2.mesh";
        //Mesh3T4 mesh = mg.readMesh(meshFile, MeshFormat.mesh);
        String dataFile = dir + "TGT100_75000m.dat";
        Scanner scanner = null;
        try {
            scanner = new Scanner(new File(dataFile));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        int numberOfNodes = scanner.nextInt();
        int numberOfElements = scanner.nextInt();
        double[][] nodesData = new double[numberOfNodes][];
        double[] pressureData = new double[numberOfNodes];
        double[] heatFluxData = new double[numberOfNodes];
        double[] fricData = new double[numberOfNodes];
        double[] xyz0 = new double[3];
        for(int i = 0; i < numberOfNodes; i++) {
            nodesData[i] = new double[3];
            nodesData[i][0] = scanner.nextDouble();
            nodesData[i][1] = scanner.nextDouble();
            nodesData[i][2] = scanner.nextDouble();
            fricData[i]     = scanner.nextDouble();
            pressureData[i] = scanner.nextDouble();
            heatFluxData[i] = scanner.nextDouble();
        }
        int[][] elesData = new int[numberOfElements][];
        for(int i = 0; i < numberOfElements; i++) {
            elesData[i] = new int[3];
            elesData[i][0] = scanner.nextInt() - 1;
            elesData[i][1] = scanner.nextInt() - 1;
            elesData[i][2] = scanner.nextInt() - 1;
        }

        Mesh3T3SGenerator mg = new Mesh3T3SGenerator();
        Mesh3T3S mesh = mg.constructMesh(nodesData, elesData);
        mesh.saveMesh("WholeMesh.msh");

        ScalarFunc rightRegion = (xyz, label, param) -> {
            double x = xyz[0], y = xyz[1], z = xyz[2];
            double rY = -0.55, rZ = 0.0, radius = 0.3368;
            double l = (y - rY) * (y - rY) + (z - rZ) * (z - rZ);
            if (l < radius * radius) {
                return -1.0;
            }
            return 1.0;
        };
        mesh.removeElements(rightRegion, null, 1);
        //mesh.removeElements(elesToRemove, 4);
        mesh.toTecplot(dir + "ReducedMesh.dat");
        mesh.saveMesh_mesh(dir + "DaQiPing4.mesh");
        */

        /*
        String dir = "C:\\Users\\Administrator\\OneDrive\\TianGongComputation\\T100Computations\\";
        Mesh3T3SGenerator mg = new Mesh3T3SGenerator();
        Mesh3T3S mesh = mg.readMesh(dir + "WholeMesh.msh");
        Mesh3T3S meshXQP1 = mg.readMeshFile(dir + "QiPing.mesh");
        Mesh3T3S meshXQP2 = mg.readMeshFile(dir + "QiPing2.mesh");
        Mesh3T3S meshXQP3 = mg.readMeshFile(dir + "QiPing3.mesh");
        Mesh3T3S meshXQP4 = mg.readMeshFile(dir + "QiPing4.mesh");
        Mesh3T3S meshQP1 = mg.readMeshFile(dir + "DaQiPing.mesh");
        Mesh3T3S meshQP2 = mg.readMeshFile(dir + "DaQiPing2.mesh");
        Mesh3T3S meshQP3 = mg.readMeshFile(dir + "DaQiPing3.mesh");
        Mesh3T3S meshQP4 = mg.readMeshFile(dir + "DaQiPing4.mesh");
        mesh.removeMesh(meshXQP1, 2);
        mesh.removeMesh(meshXQP2, 2);
        mesh.removeMesh(meshXQP3, 2);
        mesh.removeMesh(meshXQP4, 2);
        mesh.removeMesh(meshQP1, 2);
        mesh.removeMesh(meshQP2, 2);
        mesh.removeMesh(meshQP3, 2);
        mesh.removeMesh(meshQP4, 2);
        mesh.toTecplot(dir + "ReducedMesh.dat");
        mesh.saveMesh_mesh(dir + "remainedMesh.mesh");

         */

        /*
        String dir = "C:\\Users\\Administrator\\OneDrive\\TianGongComputation\\T100Computations\\";
        Mesh3T3SGenerator mg = new Mesh3T3SGenerator();
        Mesh3T3S mesh = mg.readMeshFile(dir + "remainedMesh.mesh");
        ScalarFunc rightRegion = (xyz, label, param) -> {
            double x = xyz[0], y = xyz[1], z = xyz[2];
            double rY = 0.0, rZ = 0.0, radius = 0.95;
            double l = (y - rY) * (y - rY) + (z - rZ) * (z - rZ);
            if (x > 0.029999) {
                if (l < radius * radius) {
                    return -1.0;
                }
            }
            return 1.0;
        };
        mesh.removeElements(rightRegion, null, 1);
        mesh.toTecplot(dir + "ReducedMesh.dat");
        mesh.saveMesh_mesh(dir + "BottonMesh.mesh");
        ScalarFunc rightRegion2 = (xyz, label, param) -> {
            double x = xyz[0], y = xyz[1], z = xyz[2];
            if (x > 0.029999) {
                if (y + z > 0.06 && z - y > 0.06) {
                    return 1.0;
                }
                if (y + z < -0.06 && -z + y < -0.06) {
                    return 1.0;
                }
                if (y + z > 0.06 && -z + y > 0.06) {
                    return 1.0;
                }
                if (y + z < -0.06 && z - y < -0.06) {
                    return 1.0;
                }
            }
            return -1.0;
        };
        mesh.removeElements(rightRegion2, null, 1);
        //mesh.toTecplot(dir + "ReducedMesh.dat");
        int[] elesToRemove = new int[1022];
        Arrays.setAll(elesToRemove, i-> 5336 + i);
        mesh.removeElements(elesToRemove, 1);
        mesh.toTecplot(dir + "ReducedMesh.dat");
        mesh.saveMesh_mesh(dir +"ShiZiJia.mesh");

        Mesh3T3S OriginalMesh = mg.readMeshFile(dir + "remainedMesh.mesh");
        OriginalMesh.removeMesh(mesh, 10);
        //OriginalMesh.toTecplot(dir + "MyReducedMesh.dat");
        //OriginalMesh.saveMesh_mesh(dir + "MyReducedMesh.mesh");
        ScalarFunc rightRegion3 = (xyz, label, param) -> xyz[0] < -0.2?-1.0:1.0;
        OriginalMesh.removeElements(rightRegion3, null, 2);
        OriginalMesh.toTecplot(dir+"Ring.dat");
        OriginalMesh.saveMesh_mesh(dir + "Ring.mesh");

         */


        /*
        ScalarFunc rightRegion = (xyz, label, param) -> {
            double x = xyz[0], y = xyz[1], z = xyz[2];
            double rY = 0.53, rZ = -0.53, radius = 0.175;
            double l = (y - rY) * (y - rY) + (z - rZ) * (z - rZ);
            if (x > -0.8 && x < -0.06) {
                if (l < radius * radius) {
                    return -1.0;
                }
            }
            if (x > -0.06 && x < -0.01) {
                if (l < (radius - 0.0355) * (radius - 0.0355)) {
                    return -1.0;
                }
            }
            return 1.0;
        };
        mesh.removeElements(rightRegion, null, 1);
        int[] elesToRemove = {
                120, 119, 118, 117, 116, 115, 114, 113, 112, 111,
                110, 109, 108, 107, 106, 105, 104, 103, 102, 101,
                100, 99, 98, 97, 96, 95, 94, 93, 92, 91,
                90, 89, 88, 87, 86, 85, 84, 83, 82, 81,
                80, 79, 78, 77, 76, 75, 74, 73, 72, 71,
                70, 69, 68, 67, 66, 65, 64, 63, 62, 61,
                60, 59, 58, 57, 56, 55, 54, 53, 52, 51,
                50, 49, 48, 47, 46, 45, 44, 43, 42, 41,
                40, 39, 38, 37, 36, 35, 34, 33, 32, 31,
                30, 29, 28, 27, 26, 25, 24, 23, 22, 21,
                20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
                10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
                121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
                131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
                141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
                151, 152, 153, 154, 155, 156, 157, 158, 159, 160,
                161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
                171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
//                175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186,
//                187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203
//                204, 205, 206, 207,208, 209, 210, 211, 212, 213, 214, 215, 216, 217,218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
                };
        //        int[] elesToRemove = {119
        //       };
        mesh.removeElements(elesToRemove, 4);
        mesh.toTecplot(dir + "ReducedMesh.dat");
        mesh.saveMesh_mesh(dir + "QiPing4.mesh");
        //mesh.saveMesh("MyHalf2DD.msh");*/

//        String dir = "C:\\Users\\Administrator\\OneDrive\\TianGongComputation\\T100Computations\\";
//        Mesh3T3SGenerator mg = new Mesh3T3SGenerator();
//        Mesh3T3S mesh = mg.readMeshFile(dir + "QiPing.mesh");
//        mesh.toTecplot(dir + "QiPing1.dat");
//        double[] xyz = {-0.3, 0.51, 0.51};
//        mesh.shrink(xyz, 0.1);
//        mesh.toTecplot(dir + "ShinkedQiPing1.dat");
//        Mesh3T3S orginalMesh = mg.readMeshFile(dir + "QiPing.mesh");
//        orginalMesh.add(mesh);
//        mesh.toTecplot(dir + "HollowQiPing1.dat");

//        mesh.toTecplot("WholeMesh2D.dat");
//        ScalarFunc removeRegion1 = (xyz, label, param) -> {
//            double x = xyz[0], y = xyz[1];
//            if (y < -1.387 && x < -2.172 && x > -2.682) {
//                return 1.0;
//            }
//            return -1.0;
//        };
//        mesh.removeElements(removeRegion1, null, 2);
//        ScalarFunc removeRegion2 = (xyz, label, param) -> xyz[0] > -0.012?1.0:-1.0;
//        mesh.removeElements(removeRegion2, null, 3);
//        ScalarFunc removeRegion3 = (xyz, label, param) -> {
//            double x = xyz[0], y = xyz[1], z = xyz[2];
//            if (y > 1.386 && x > -3.008 && x < -2.52) {
//                return 1.0;
//            }
//            return -1.0;
//        };
//        mesh.removeElements(removeRegion3, null, 4);
//        mesh.toTecplot("TianGong3D2C.dat");
//        mesh.saveMesh("2CSurfaceMesh.dat");
        //scanner.close();


        /*
        String file = "Half2Dmesh.msh";
        Mesh3T3SGenerator mg = new Mesh3T3SGenerator();
        Mesh3T3S mesh = mg.readMesh(file);
        mesh.toTecplot("2CMeshShell.dat");
        mesh.displayBoundarys();
        mesh.saveMesh_mesh("SurfaceMeshForFF.mesh");

         */


//        dataFile = dir + "TG-ALL_90000m.dat";
//        try {
//            scanner = new Scanner(new File(dataFile));
//        } catch (FileNotFoundException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
//        numberOfNodes = scanner.nextInt();
//        numberOfElements = scanner.nextInt();
//        nodesData = new double[numberOfNodes][];
//        pressureData = new double[numberOfNodes];
//        heatFluxData = new double[numberOfNodes];
//        fricData = new double[numberOfNodes];
//        double[] data1Data = new double[numberOfNodes];
//        double[] data2Data = new double[numberOfNodes];
//        double[] data3Data = new double[numberOfNodes];
//        for(int i = 0; i < numberOfNodes; i++) {
//            nodesData[i] = new double[3];
//            nodesData[i][0] = scanner.nextDouble();
//            nodesData[i][1] = scanner.nextDouble();
//            nodesData[i][2] = scanner.nextDouble();
//            fricData[i]     = scanner.nextDouble();
//            pressureData[i] = scanner.nextDouble();
//            heatFluxData[i] = scanner.nextDouble();
//            data1Data[i] = scanner.nextDouble();
//            data2Data[i] = scanner.nextDouble();
//            data3Data[i] = scanner.nextDouble();
//        }
//        elesData = new int[numberOfElements][];
//        for(int i = 0; i < numberOfElements; i++) {
//            elesData[i] = new int[3];
//            elesData[i][0] = scanner.nextInt() - 1;
//            elesData[i][1] = scanner.nextInt() - 1;
//            elesData[i][2] = scanner.nextInt() - 1;
//        }
//        Mesh3T3S mesh2 = mg.constructMesh(nodesData, elesData);
//        mesh2.toTecplot("TianGong3DAll.dat");
//        String meshFile = dir + "MainEngine.mesh";
//        Mesh3T4Generator mg = new Mesh3T4Generator();
//        Mesh3T4 mesh = mg.readMesh(meshFile, MeshFormat.mesh);
//        System.out.println("Basic mesh information: ");
//        System.out.println(mesh.getNv() + "\t" + mesh.getNt() + "\t" + mesh.getNb());
//        mesh.toTecplot(dir + "MainEngineMesh.dat");
//        HashSet<Integer> bdNodes = mesh.extractBoundaryNodes(0);


        /*
        String dir = "TianGongMeshes\\";
        String dataFile = dir + "TG-2C_80000m.dat";

        Scanner scanner = null;
        try {
            scanner = new Scanner(new File(dataFile));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        int numberOfNodes = scanner.nextInt();
        int numberOfElements = scanner.nextInt();
        double[][] nodesData = new double[numberOfNodes][];
        double[] pressureData = new double[numberOfNodes];
        double[] heatFluxData = new double[numberOfNodes];
        double[] fricData = new double[numberOfNodes];
        double[] xyz0 = new double[3];
        for(int i = 0; i < numberOfNodes; i++) {
            nodesData[i] = new double[3];
            nodesData[i][0] = scanner.nextDouble();
            nodesData[i][1] = scanner.nextDouble();
            nodesData[i][2] = scanner.nextDouble();
            fricData[i]     = scanner.nextDouble();
            pressureData[i] = scanner.nextDouble();
            heatFluxData[i] = scanner.nextDouble();
        }
        int[][] elesData = new int[numberOfElements][];
        for(int i = 0; i < numberOfElements; i++) {
            elesData[i] = new int[3];
            elesData[i][0] = scanner.nextInt() - 1;
            elesData[i][1] = scanner.nextInt() - 1;
            elesData[i][2] = scanner.nextInt() - 1;
        }
        Mesh3T3SGenerator mg = new Mesh3T3SGenerator();
        Mesh3T3S mesh = mg.constructMesh(nodesData, elesData);
        ScalarFunc rightRegion = (xyz, label, param) -> Math.abs(xyz[0]) > 1.0e-4?1.0:-1.0;
        mesh.removeElements(rightRegion, null, 1);
        ScalarFunc removeRegion3 = (xyz, label, param) -> {
            double x = xyz[0], y = xyz[1], z = xyz[2];
            if (z > -0.03 && z < 0.03) {
                if (y > 0.86915 && y < 0.92555) {
                    return 1.0;
                }
                if (y > 1.01917 && y < 1.07955) {
                    return 1.0;
                }
                if (y > -1.07555 && y < -1.01917) {
                    return 1.0;
                }
                if (y > -0.92555 && y < -0.86915) {
                    return 1.0;
                }
            }
            if (y > -0.03 && y < 0.03) {
                if (z > 0.86915 && z < 0.92555) {
                    return 1.0;
                }
                if (z > 1.01917 && z < 1.07955) {
                    return 1.0;
                }
                if (z > -1.07555 && z < -1.01917) {
                    return 1.0;
                }
                if (z > -0.92555 && z < -0.86915) {
                    return 1.0;
                }
            }

            return -1.0;
        };
        mesh.removeElements(removeRegion3, null, 4);
        mesh.toTecplot("backSurface.dat");
        mesh.saveMesh("MyBackSurface.msh");
        */

        /*
        Mesh3T3SGenerator mg = new Mesh3T3SGenerator();
        Mesh3T3S mesh = mg.readMesh("MyBackSurface.msh");
        mesh.toTecplot("MyBackSurfaceMy.dat");
        mesh.saveMesh_mesh("TianGongBackSurface.mesh");
        */
//        int nv = mesh.getNv();
//
//        double[] fricData = ;
////		boolean[] flag = new boolean[nv];
//
//
//        int count = 0;
//
//
//
//
//        ArrayList<double[]> data = new ArrayList<>();
//        while(scanner.hasNextDouble()) {
//            double xyz1 = scanner.nextDouble();
//            double xyz2 = scanner.nextDouble();
//            double xyz3 = scanner.nextDouble();
//            double pres = scanner.nextDouble();
//            double flux = scanner.nextDouble();
//            data.add(new double[] {xyz1, xyz2, xyz3, pres, flux});
//        }
//
//        double min = 1.0e10;
//        int idx = -1;
//        boolean flag = false;
//        for(int i = 0; i < nv; i++) {
//            double[] xyz = mesh.getNode(i);
//            xyz[2] = Math.abs(xyz[2]);
//            min = 1.0e10;
//            idx = -1;
//            flag = false;
//            for(int j = 0; j < data.size(); j++) {
//                double[] d = data.get(j);
//                d[2] = Math.abs(d[2]);
//                double err0 = Math.sqrt((d[0] - xyz[0]) * (d[0] - xyz[0]) + (d[1] - xyz[1]) * (d[1] - xyz[1]) + (d[2] - xyz[2]) * (d[2] - xyz[2]));
//                if (min > err0) {
//                    min = err0;
//                    idx = j;
//                }
//                if (err0 < 1.0e-6) {
//                    pressureData[i] = d[3];
//                    heatFluxData[i] = d[4];
//                    System.out.println("count: " + (++count));
//                    flag = true;
//                    break;
//                }
//            }
//            if(!flag) {
//                double[] dd = data.get(idx);
//                pressureData[i] = dd[3];
//                heatFluxData[i] = dd[4];
//                System.out.println("count: " + (++count));
//            }
//        }
//        System.out.println("Total Nodes:" + mesh.getNv());
//        System.out.println("Surface Nodes: " + bdNodes.size());
//        scanner.close();
//        mesh.toTecplot(dir + "PressureData-20.dat", pressureData);
//        mesh.toTecplot(dir + "heatData-20.dat", heatFluxData);
//        MVO.saveArray(dir + "MainEnginePressure-20.dat", pressureData);
//        MVO.saveArray(dir + "MainEngineHeatflux-20.dat", heatFluxData);
    }
}
